#pragma once

#include <iostream>
#include <string>
#include <jsoncpp/json/json.h>

//#define Myself 1

using namespace std;
const std::string blank_space_sep = " ";
const std::string protocol_sep = "\n";

//封装报头
std::string Encode(const std::string &content)
{

    std::string packge = std::to_string(content.size());
    packge += protocol_sep;
    packge += content;
    packge += protocol_sep;
    return packge;
}
//"len""\n""x op y""\n"
bool Decode(std::string &package, std::string* content)
{
    size_t pos = package.find(protocol_sep);
     if(pos == std::string::npos)
    {
        return false;
    } 
    std::string len_str = package.substr(0, pos);
    size_t len = std::stoi(package.substr(0, pos));
    //packge  = len_str + content_str + 2
    size_t total_len = len_str.size() + len + 2;
    if(package.size() < total_len) //可能还有一些其他的数据，但是我们不关心
    {
        return false;
    }
    *content = package.substr(pos + 1, len);
    //earse 移除报文 package.erase(0, total_len)
    package.erase(0, total_len);
    return true;
}

class Request
{
public: 
    Request(int data1, int data2, char oper)
        :x(data1)
        ,y(data2)
        ,op(oper)
    {}
    Request()
    {}
public:
    bool Serialize(std::string *out)
    {
#ifdef Myself
        //构建报文的有效载荷
        //struct => string, x op y  ==> "x op y"
        std::string s = std::to_string(x);
        s += blank_space_sep;
        s += op;
        s += blank_space_sep;
        s += std::to_string(y);
        *out = s;
#else 
        Json::Value root;
        root["x"] = x;
        root["y"] = y;
        root["op"] = op;
        Json::StyledWriter w;
        //Json::FastWriter w;
        *out = w.write(root);
#endif
        return true;
    }
    bool Deserialize(const std::string& in) //"x op y"
    {
#ifdef Myself
        size_t left = in.find(blank_space_sep);
        if(left == std::string::npos)
        {
            return false;
        }
        std::string part_x = in.substr(0, left);

        size_t right = in.rfind(blank_space_sep);
        if(right == std::string::npos)
        {
            return false;
        }   
        std::string part_y = in.substr(right + 1);
        if(left + 2 != right)
        {
            return false;
        }

        op = in[left + 1];
        x = std::stoi(part_x);
        y = std::stoi(part_y);
#else 
        Json::Value root;
        Json::Reader r;
        r.parse(in, root);
        x = root["x"].asInt();
        y = root["y"].asInt();
        op = root["op"].asInt();
#endif
        return true;
    }
    void DebugPrint()
    {
        std::cout << "新请求构建完成: " << x << op << y << "=?" << endl;
    }
public:
    int x;
    int y;
    char op; // + - * / %
};


class Response
{
public:
    Response(int res, int c)
        :result(res)
        ,code(c)
    {}
    Response()
    {}
public:
    bool Serialize(std::string *out)
    {
#ifdef Myself
        //"result code"

        //构建报文的有效载荷
        std::string s = std::to_string(result);
        s += blank_space_sep;
        s += std::to_string(code);
        *out = s;
#else 
        Json::Value root;
        root["result"] = result;
        root["code"] = code;
        Json::StyledWriter w;
        //Json::FastWriter w;
        *out = w.write(root);
#endif
        return true;
    }
    //"result code"
    bool Deserialize(const std::string& in)
    {
#ifdef Myself
        std::size_t pos = in.find(blank_space_sep);
        if(pos == std::string::npos)
        {
            return false;
        }
        std::string part_left = in.substr(0, pos);
        std::string part_right = in.substr(pos + 1);
        result = std::stoi(part_left);
        code = std::stoi(part_right);
#else 
        Json::Value root;
        Json::Reader r;
        r.parse(in, root);
        result = root["result"].asInt();
        code = root["code"].asInt();
#endif
        return true;
    }
    void DebugPrint()
    {
        std::cout << "结果响应完成: result: " << result << ", code: " << code << endl;
    }
public:
    int result;
    int code; // 0 可信,非零不可信,具体是几,表明错误原因。
};